package br.mikhas.lang.compiler.parser;

import br.mikhas.util.ExceptionUtils;

public abstract class CharStream {

	protected Position position = new Position();

	protected abstract char charAt(int index);

	char lookAhead(int offset) {
		return charAt(position.index + offset);
	}

	char next() {
		char c = charAt(position.index);
		position.index++;
		position.column++;

		if (c == '\n') {
			position.line++;
			position.column = 1;
		}

		return c;
	}

	Position getPosition() {
		try {
			return this.position.clone();
		} catch (CloneNotSupportedException e) {
			// Shoud not happen
			throw ExceptionUtils.wrapChecked(e);
		}
	}

	void setPosition(Position position) {
		this.position = position;
	}

	class Position implements Cloneable {
		private int line = 1;
		private int column = 1;
		private int index;

		int getLine() {
			return this.line;
		}

		int getColumn() {
			return this.column;
		}

		int getIndex() {
			return this.index;
		}

		@Override
		protected Position clone() throws CloneNotSupportedException {
			Position clone = new Position();
			clone.index = index;
			clone.column = column;
			clone.line = line;
			return clone;
		}
	}
}
